package com.sservice.web.controller.admin;

import com.sservice.common.Constants;
import com.sservice.common.SameUrlData;
import com.sservice.model.dao.OtherReceivablesMapper;
import com.sservice.model.entity.*;
import com.sservice.model.vo.AdvanceReceiptVo;
import com.sservice.model.vo.OrderAdvanceReceiptVo;
import com.sservice.service.service.*;
import com.sservice.urp.entity.User;
import com.sservice.web.log.Action;
import com.sservice.web.controller.websocket.WebsocketEndPoint;
import com.google.gson.GsonBuilder;
import com.sservice.base.entity.dto.BaseResult;
import com.sservice.base.entity.dto.ListResult;
import com.sservice.base.entity.dto.Pagination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by suweiming on 2017/12/20.
 */

@Controller
@RequestMapping("/admin/advanceReceipt")
public class AdvanceReceiptController {
    @Resource
    WebsocketEndPoint websocket;
    @Autowired
    ExportService exportService;
    @Autowired
    IPayTypeService iPayTypeService;
    @Autowired
    private IAdvanceReceiptService service;
    @Autowired
    private IOrderAdvanceReceiptService oarService;
    @Autowired
    private ISysLogService sysLogService; //
    @Autowired
    private OtherReceivablesMapper otherMapper; //
    @Autowired
    private PurchaseOrderLogService serviceLog;

    /*
     *  查询供应商可用预付款单
     * @param arv
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/queryByClienteleId", method = RequestMethod.GET)
    public ListResult queryByClienteleId(AdvanceReceiptVo arv) {
        List service_res = service.queryByClienteleId(arv);
        ListResult<Clientele> res = new ListResult(true, service_res);
        return res;
    }

    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public BaseResult delete(AdvanceReceiptVo arv) {
        Object service_res = service.delete(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, String.valueOf(service_res), 403);
        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /***
     *
     * @param arv
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/clientele/{type}/{clienteleId}", method = RequestMethod.GET)
    public ListResult queryByClienteleIdRest(AdvanceReceiptVo arv) {
        arv.setVerifiedOver("!1");
        arv.setUnitCode(arv.getClienteleId());
        List service_res = service.queryByClienteleId(arv);
        ListResult<Clientele> res = new ListResult(true, service_res);
        return res;
    }

    /**
     * 领导审核通过
     *
     * @param arv
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/leaderCheck/{remark}/{orderId}", method = RequestMethod.GET)
    public BaseResult check(AdvanceReceiptVo arv, HttpServletRequest request) throws IOException {
        if (!(arv.getRemark().equals("1") || arv.getRemark().equals("2"))) {
            return new BaseResult(false, "非法操作!", 403);
        }
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setClienteleId(String.valueOf(user.getId()));
        arv.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        Object service_res = oarService.check(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        int res = (int) service_res;
        if (res > 0) {
            websocket.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("领导审核完毕!")),
                    "");
            sysLogService.log("核算审核：" + (arv.getRemark().equals("1") ? "通过" : "拒绝"), request, Integer.valueOf(arv.getOrderId()), Action.applyPay);

//            serviceLog.log("核算审核" + (arv.getRemark().equals("1") ? "通过" : "拒绝"), request, Integer.valueOf(arv.getOrderId()));
        }
        return new BaseResult(true, service_res.toString(), 200);
    }

    /***
     * 财务付款
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/pay/{orderId}", method = RequestMethod.GET)
    public BaseResult pay(AdvanceReceiptVo arv, String payCashDesc, String advanceReceiptId, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setOperator(String.valueOf(user.getId()));
        arv.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        arv.setClienteleName(payCashDesc);
        arv.setLocked(advanceReceiptId);

        Object service_res = oarService.pay(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        int res = (int) service_res;
        if (res > 0) {
            sysLogService.log("付款", request, Integer.valueOf(arv.getOrderId()), Action.applyPay);
        }
        return new BaseResult(true, service_res.toString(), 200);
    }

    /**
     * 已付款申请单财务退款
     *
     * @param arv
     * @param payCashDesc
     * @param advanceReceiptId
     * @param request
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/reback/{orderId}", method = RequestMethod.POST)
    public BaseResult reback(AdvanceReceiptVo arv, String payCashDesc, String advanceReceiptId, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setOperator(String.valueOf(user.getId()));
        Object service_res = oarService.reback(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        if (service_res == null) {
            sysLogService.log("删除已付款", request, Integer.valueOf(arv.getOrderId()), Action.applyPay);
        }
        return new BaseResult(true, "", 200);
    }


    /**
     * 分页查询
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/query", method = RequestMethod.GET)
    public ListResult query(AdvanceReceiptVo arv) {
        return page(arv);
    }

    @ResponseBody
    @RequestMapping(value = "/queryBy", method = RequestMethod.GET)
    public ListResult pageBy(AdvanceReceiptVo arv) {
        return service.pageBy(arv);
    }


    @ResponseBody
    @RequestMapping(value = "/query/{type}/{verifiedOver}/{clienteleId}", method = RequestMethod.GET)
    public ListResult queryRest(AdvanceReceiptVo arv) {
        return page(arv);
    }

    private ListResult page(AdvanceReceiptVo arv) {
        List service_res = service.queryByPage(arv);
        int total = service.queryCount(arv);
        Pagination page = new Pagination(arv.getPage(), total, arv.getSize());
        ListResult<Clientele> res = new ListResult(true, service_res);
        res.setPage(page);
        return res;
    }

    /***
     * 预收款单导出功能
     * @param arv
     * @return
     */
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    private OutputStream export(AdvanceReceiptVo arv, HttpServletResponse response, HttpServletRequest request) throws IOException {
        arv.setSize(Integer.MAX_VALUE);
        arv.setPage(0);
        List<AdvanceReceiptVo> list = service.queryByPage(arv);
        ServletOutputStream outputStream = response.getOutputStream();
        exportService.setResponseHeader(response, request, "预" + ("1".equals(arv.getType()) ? "收" : "付") + "款单Excel");
        String hql = "预" + ("1".equals(arv.getType()) ? "收" : "付") + "款单"; // sheet 名称
        List<PayType> pts = iPayTypeService.queryAll(new PayType());
        PayType pt = new PayType();
        pt.setType("1"); // 收款账户
        List<PayType> ptAccounts = iPayTypeService.queryAll(pt);
        List<Map> lm = new ArrayList<Map>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if ("1".equals(arv.getType())) {
            for (int i = 0; i < list.size(); i++) {
                Map map = new LinkedHashMap();
                AdvanceReceiptVo ov = list.get(i);
                map.put("预收款单号", ov.getNo());
                map.put("客户名称", ov.getClienteleName());
                map.put("付款方式", getPayType(pts, ov.getPayType()));
                map.put("付款日期", sdf.format(ov.getPayTime()));
                map.put("操作人", ov.getUserName());
                map.put("收款金额", ov.getTotalDeposit());
                map.put("核销金额", ov.getTotalVerified());
                map.put("剩余金额", ov.getTotalDeposit().subtract(ov.getTotalVerified()));
                map.put("是否核销完毕", "1".equals(ov.getVerifiedOver()) ? "是" : "否");
                map.put("创建时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
                map.put("收款账户", getPayType(ptAccounts, ov.getAccount()));
                map.put("备注", ov.getRemark());
                lm.add(map);
            }

            return exportService.exportExcel(hql, lm, outputStream);
        } else if ("2".equals(arv.getType())) {
            for (int i = 0; i < list.size(); i++) {
                Map map = new LinkedHashMap();
                AdvanceReceiptVo ov = list.get(i);
                map.put("预付款单号", ov.getNo());
                map.put("供应商名称", ov.getClienteleName());
                map.put("付款方式", getPayType(pts, ov.getPayType()));
                map.put("付款日期", sdf.format(ov.getPayTime()));
                map.put("操作人", ov.getUserName());
                map.put("付款金额", ov.getTotalDeposit());
                map.put("核销金额", ov.getTotalVerified());
                map.put("剩余金额", ov.getTotalDeposit().subtract(ov.getTotalVerified()));
                map.put("是否核销完毕", "1".equals(ov.getVerifiedOver()) ? "是" : "否");
                map.put("创建时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
                map.put("备注", ov.getRemark());
                lm.add(map);
            }
            return exportService.exportExcel(hql, lm, outputStream);
        }
        return null;
    }

    public String getPayType(List<PayType> pts, String type) {
        for (int i = 0; i < pts.size(); i++) {
            PayType pt = pts.get(i);
            if ((pt.getId().toString()).equals(type)) {
                return pt.getName();
            }
        }
        return null;
    }


    /**
     * 创建预收款单
     *
     * @param ar
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public BaseResult create(AdvanceReceipt ar, HttpSession session, HttpServletRequest request) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User user = (User) session.getAttribute(Constants.USER);
        ar.setOperator(String.valueOf(user.getId()));
        Object service_res = service.createAdvanceReceipt(ar);
        if (service_res instanceof Integer) {
            sysLogService.log("创建", request, ar.getId(), ar.getType().equals("0") ? Action.advanceReceiptType : Action.advancePayType);
        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /***
     * 创建预付款单
     * @param ar
     * @param session
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/createAdvancePay", method = RequestMethod.POST)
    public BaseResult createAdvancePay(AdvanceReceipt ar, HttpSession session, HttpServletRequest request) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User user = (User) session.getAttribute(Constants.USER);
        ar.setOperator(String.valueOf(user.getId()));
        Object service_res = service.createAdvancePay(ar);
        if (service_res instanceof Integer) {
            sysLogService.log("创建", request, ar.getId(), ar.getType().equals("0") ? Action.advancePayType : Action.advancePayType);
        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/destoryAdvancePay", method = RequestMethod.POST)
    public BaseResult destoryAdvancePay(AdvanceReceipt ar, HttpSession session, HttpServletRequest request) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Object service_res = service.destoryAdvancePay(ar);
        if (service_res instanceof Integer) {
            sysLogService.log("删除预" + (ar.getType().equals("0") ? "付" : "收") + "款单数据", request, ar.getId(), ar.getType().equals("0") ? Action.advancePayType : Action.advancePayType);
        }
        return new BaseResult(true, service_res);
    }

    /***
     *  付款单支付订单情况
     * @param ar
     * @param session
     * @param request
     * @return
     * @throws NoSuchMethodException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/payedToOrder", method = RequestMethod.POST)
    public BaseResult payedToOrder(AdvanceReceipt ar, HttpSession session, HttpServletRequest request) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User user = (User) session.getAttribute(Constants.USER);
        ar.setOperator(String.valueOf(user.getId()));
        Object service_res = service.createAdvancePay(ar);
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /**
     * 账户余额支付销售订单
     *
     * @param ar
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/payOrder", method = RequestMethod.POST)
    public BaseResult payOrder(OrderAdvanceReceiptVo ar, HttpServletRequest request) {
        ar.setOperator(String.valueOf(getUser(request).getId()));
        Object service_res = oarService.payOrder(ar);
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    /***
     *  核算锁定
     * @param ar
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/lock", method = RequestMethod.POST)
    public BaseResult lock(OrderAdvanceReceiptVo ar, HttpServletRequest request) throws IOException {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        ar.setClienteleId(String.valueOf(user.getId()));
        ar.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        Object service_res = oarService.lockAdvanceBill(ar, getUser(request).getId());
        if (service_res instanceof Integer) {
            int res = (int) service_res;
            websocket.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("" + "核算完毕!")), "");
            sysLogService.log("核算", request, (Integer) service_res, Action.applyPay);
        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }


    /***
     * 其他应付
     * @param ar
     * @param request
     * @return
     * @throws IOException
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/other/lock", method = RequestMethod.POST)
    public BaseResult Otherlock(OrderAdvanceReceiptVo ar, HttpServletRequest request) throws IOException {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        ar.setClienteleId(String.valueOf(user.getId()));
        ar.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        Object service_res = oarService.otherLockAdvanceBill(ar, getUser(request).getId());
        if (service_res instanceof Integer) {
            int res = (int) service_res;
            websocket.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("" + "核算完毕!")),
                    "");
            OtherReceivables po = otherMapper.selectByPrimaryKey(Integer.valueOf(ar.getOrderIdDesc()));
            sysLogService.log("核算", request, po.getId(), po.getType().equals("0") ? Action.otherReceiableType : Action.otherPayType);

        }
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/other/leaderCheck/{remark}/{orderId}", method = RequestMethod.GET)
    public BaseResult otherCheck(AdvanceReceiptVo arv, HttpServletRequest request) throws IOException {
        if (!(arv.getRemark().equals("1") || arv.getRemark().equals("2"))) {
            return new BaseResult(false, "非法操作!", 403);
        }
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setClienteleId(String.valueOf(user.getId()));
        arv.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        Object service_res = oarService.otherCheck(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        int res = (int) service_res;
        if (res > 0) {
            websocket.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("领导审核完毕!")),
                    "");
            OtherReceivables po = otherMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
            sysLogService.log("审核" + ("1".equals(arv.getRemark()) ? "通过" : "拒绝"), request, po.getId(), po.getType().equals("0") ? Action.otherReceiableType : Action.otherPayType);
        }
        return new BaseResult(true, service_res.toString(), 200);
    }

    /***
     * 财务付款
     * @param arv
     * @param request
     * @return
     */
    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/other/pay/{orderId}", method = RequestMethod.GET)
    public BaseResult otherPay(AdvanceReceiptVo arv, String payCashDesc, String advanceReceiptId, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        arv.setOperator(String.valueOf(user.getId()));
        arv.setUserName(user.getName() != null ? user.getName() : user.getUserName());
        arv.setClienteleName(payCashDesc);
        arv.setLocked(advanceReceiptId);

        Object service_res = oarService.otherPay(arv);
        if (service_res instanceof String) {
            return new BaseResult(false, service_res.toString(), 403);
        }
        int res = (int) service_res;
        if (res > 0) {
//            serviceLog.log("付款", request, Integer.valueOf(arv.getOrderId()));
            OtherReceivables po = otherMapper.selectByPrimaryKey(Integer.valueOf(arv.getOrderId()));
            sysLogService.log("付款", request, po.getId(), po.getType().equals("0") ? Action.otherReceiableType : Action.otherPayType);
        }
        return new BaseResult(true, service_res.toString(), 200);
    }

    private User getUser(HttpServletRequest request) {
        return (User) request.getSession().getAttribute(Constants.USER);
    }


    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public BaseResult update(AdvanceReceipt ar) {
        int service_res = service.updateByPrimaryKeySelective(ar);
        BaseResult res = new BaseResult(true, service_res);
        return res;
    }

    @ResponseBody
    @SameUrlData
    @RequestMapping(value = "/detail/{id}", method = RequestMethod.GET)
    public BaseResult detail(AdvanceReceipt ar) {
        return new BaseResult(true, service.selectByPrimaryKey(ar.getId()));
    }


}
